<gm:page title="Using the JavaScript GData Library in GME" authenticate="false" onload="onLoad()">

  <style>
    h3 {
      margin: 0px;
      text-align: center;
    }
    h4 {
      margin-bottom: 3px;
    }
    th {
      background-color: #EEEEEE;
    }
    #eventsListTable {
      margin-bottom: 15px;
      width: 100%;
    } 
    #eventTimesTable td {
      padding-right: 5px;
    }
    #newEventItemContainer {
      background-color: #C3D9FF;
      border: solid silver 1px;
      padding: 8px;
    }
  </style>  
  
  
  <script src="http://www.google.com/jsapi?key=ABQIAAAAV89cBTjirjESYXH8lQLSPhT3sUencwn6gNcPFXZZYDpXvzZlIBQTbP25zq1dka4Zu5G50HsrTgu48A" type="text/javascript"></script>
     
  
  <script>
    // Load the Google data JS Client Library
    google.load("gdata", "1");
  
    // google.gdata.calendar.CalendarService object that is used to access private feeds using AuthSub
    var myService;
    
    // Feed object containing calendar entries, one per calendar owned by authenticated user
    var calendarsFeed; 
    
    // Feed object containing event entries for selected calendar
    var eventsFeed;
    
    // URL to authenticate against, including all URLs below it
    //var authenticationURL = 'http://www.google.com/calendar/feeds/';
    var authenticationURL = 'http://www.google.com/base/';
    
    var calendarsFeedURL = 'http://www.google.com/base/feeds/items/-/hike+reviews';
    
    // URL of selected calendar
    var eventsFeedURL;
    
    
    /**
     * onload handler: calls authenticate() if necessary; otherwise, retrieves user's calendars feed
     * and resets interface
     */
    function onLoad() {     
      if (google.accounts.user.checkLogin(authenticationURL)) {
        google.gdata.client.init();
        
        //myService = new google.gdata.calendar.CalendarService('Google-GData_Calendar_Mash-1.0');
        myService = new google.gdata.client.GoogleService('Google-GData_Calendar_Mash-1.0'); 
    
        //var calendarsFeedURL = 'http://www.google.com/calendar/feeds/default/owncalendars/full';


        //myService.getOwnCalendarsFeed(calendarsFeedURL, calendarsFeedHandler, calendarsFeedError);
        myService.getFeed(calendarsFeedURL,calendarsFeedHandler, calendarsFeedError, google.gdata.Feed.constructor, true);
    
    
        document.getElementById('calendarSelect').style.display = 'block';
        document.getElementById('authenticationButton').value = 'Sign out';
        document.getElementById('authenticationButton').onclick = logout;       
      }
    };
    
    function newLoad(){
       myService.getFeed(calendarsFeedURL,calendarsFeedHandler, calendarsFeedError, google.gdata.Feed.constructor, true);
      //myService.getOwnCalendarsFeed(calendarsFeedURL, calendarsFeedHandler, calendarsFeedError);
    }
    
    
function encode_utf8( s )
{
  return unescape( encodeURIComponent( s ) );
}

function decode_utf8( s )
{
    try {
      var r = decodeURIComponent( escape( s ) );
      return r;
    } catch (error){    
    }
  return s;
}
    
    /**
     * Requests an AuthSub token for interaction with the Calendar service
     */
    function authenticate() {
      var token = google.accounts.user.login(authenticationURL);
    
    };

    /**
     * Revokes the AuthSub token and resets the page, hiding authentication-only page elements and
     * deleting list of events
     */
    function logout(){
      google.accounts.user.logout();
      document.getElementById('authenticationButton').value = 'Retrieve my calendars';
      document.getElementById('authenticationButton').onclick = authenticate;
      document.getElementById('authenticatedContent').style.display = 'none';
      document.getElementById('calendarSelect').style.display = 'none';
      deleteList('eventsList');
    };
    
    
    var entrySample;
    /**
     * Called after successful retrieval of calendars feed; populates drop-down menu with list of
     * calendars owned by user
     *
     * @param calendarsFeedRoot  JSON object containing collection of calendar entries
     */
    function calendarsFeedHandler(calendarsFeedRoot) {
      //alert(calendarsFeedRoot);
    
      calendarsFeed = calendarsFeedRoot.feed;
      //calendarsFeed = new google.gdata.Feed(calendarsFeedRoot.feed);
    
      //var calendarEntries = calendarsFeed.getEntries();
      var calendarEntries = calendarsFeed.entry;
      
      var select = document.getElementById('calendarSelect');
      for (var i=0; i<calendarEntries.length; i++) {
        var calendarEntry = calendarEntries[i];
        entrySample = calendarEntry;
        entrySample.xmlns$g = 'http://base.google.com/ns/1.0';
        entrySample.xmlns$gd='http://schemas.google.com/g/2005';
        entrySample.xmlns='http://www.w3.org/2005/Atom';
        
        var newOption = document.createElement('option');
        newOption.innerHTML = decode_utf8(calendarEntry.title.$t) + " - " + calendarEntry.g$distance[0].$t;
        //alert(calendarEntry.getContent().getText());
        newOption.value = decode_utf8(calendarEntry.title.$t);
        select.appendChild(newOption);
      }
    };
      
    /**
     * Creates a popup alert notifying user of error while attempting to retrieve user's calendars
     * feed
     * 
     * @param e  Error message string
     */
    function calendarsFeedError(e) {
      document.getElementById('authenticatedContent').style.display = 'none';
      document.getElementById('calendarSelect').style.display = 'none';
      alert(e);
    };

    /**
     * Called when user selects new calendar from drop-down; determines URL for selected calendar
     * and fetches its events feed
     */
    function changeCalendar() {
      if (google.mashups.getObjectById('eventsList').getData().size() > 0) {
        deleteList('eventsList');
        changeCalendar();
        return;
      }
        
      var calendarSelect = document.getElementById('calendarSelect');
      var selectedOption = calendarSelect.options[calendarSelect.selectedIndex];
      if (selectedOption.value != '') {
        document.getElementById('authenticatedContent').style.display = 'block';
		for (var i=0; i<calendarsFeed.getEntries().length; i++) {
          var calendarEntry = calendarsFeed.getEntries()[i];
          if (calendarEntry.getTitle().getText() == selectedOption.value) {
            eventsFeedURL = calendarEntry.getLink('alternate').getHref(); // URL of selected calendar
            
            var query = new google.gdata.calendar.CalendarEventQuery(eventsFeedURL);
            query.setOrderBy('starttime');
            query.setSortOrder('ascending');
            query.setFutureEvents(true);
            query.setSingleEvents(true);
            
            myService.getEventsFeed(query, eventsFeedHandler, eventsFeedError);
            break;
          }
        }
      }
      else {
        document.getElementById('authenticatedContent').style.display = 'none';
      }
    };
      
	/**
	 * Called after successful retrieval of events feed; copies all event entries into GME data
	 * source which is displayed to user as list
	 *
	 * @param eventsFeedRoot  JSON object containing collection of event entries
	 */
	function eventsFeedHandler(eventsFeedRoot) {
	  var eventsList = google.mashups.getObjectById('eventsList');
	  eventsFeed = eventsFeedRoot.feed;
    
          for (var i=0; i<eventsFeed.getEntries().length; i++) {
	    var eventEntry = eventsFeed.getEntries()[i];
            var location = eventEntry.getLocations()[0].getValueString();
            var startTime = google.gdata.DateTime.toIso8601(eventEntry.getTimes()[0].getStartTime().getDate());
	    var endTime = google.gdata.DateTime.toIso8601(eventEntry.getTimes()[0].getEndTime().getDate());
	  
	    var newEntry = eventsList.getData().createEntry();
	    new GPath('atom:title').setValue(newEntry, eventEntry.getTitle().getText());
            new GPath('gd:when/@startTime').setValue(newEntry, startTime);
	    new GPath('gd:when/@endTime').setValue(newEntry, endTime);

            if (location) {
              new GPath('gd:where/@valueString').setValue(newEntry, location);
            }
	  
	    eventsList.getData().addEntry(newEntry);
	  }
    };
      
    /**
     * Creates a popup alert notifying user of error while attempting to retrieve events feed for
     * selected calendar
     * 
     * @param e  Error message string
     */
    function eventsFeedError(e) {
      alert(e);
    };
      
    /**
     * Called after user creates new calendar event; copies entry into eventsList and attempts to
     * insert it into calendar feed
     */
    function addNewEvent() {
      var newEventsList = google.mashups.getObjectById('newEventsList');
      
      if (newEventsList.getData().size() > 0) {
        var entry = newEventsList.getData().entryAt(newEventsList.getData().size()-1);
        var clonedEntry = GPath.cloneEntry(entry);
        deleteList('newEventsList');

        var newEntry = new google.gdata.calendar.CalendarEventEntry();
        newEntry.setTitle(google.gdata.Text.create(new GPath('atom:title').getValue(clonedEntry)));
        newEntry.addLocation(new google.gdata.Where({valueString: new GPath('gd:where/@valueString').getValue(clonedEntry)}));
        
        var startString = new GPath('gd:when/@startTime').getValue(entry);
		var endString = new GPath('gd:when/@endTime').getValue(entry);
        
        var startTime = new GPath('gmd:startTime').getValue(entry);
        var endTime = new GPath('gmd:endTime').getValue(entry);
        
        if (startTime.length == 4) {
          startTime = '0' + startTime;
        }
        if (endTime.length == 4) {
          endTime = '0' + endTime;
        }
        
        startString += 'T'+startTime+':00.000';		
        endString += 'T'+endTime+':00.000';
        
        var timezoneOffset = getTimezoneOffset();
        var eventTimes = new google.gdata.When();
        eventTimes.setStartTime(google.gdata.DateTime.fromIso8601(startString+timezoneOffset));
        eventTimes.setEndTime(google.gdata.DateTime.fromIso8601(endString+timezoneOffset));
        newEntry.addTime(eventTimes);
                
        myService.insertEntry(eventsFeedURL, newEntry, insertEntryHandler, insertEntryError);
      }
    };
    
    
    function addStuff() {
      eventsFeedURL = "http://www.google.com/base/feeds/items";
      //var newEntry =  new google.gdata.Entry();
      //newEntry.setTitle("trilha do poderoso masher");

      
      
   //   var newEntry = new google.gdata.Entry({
//    title:       {type: 'text', text: 'Tennis with Darcy'},
//     g$item_type: [{type: 'text', text: 'Hike Reviews'}]
//      }
//    );
     
      //  "title":{"type":"text","$t":"Caminho da Gurita XXX"},
     //  "g$item_type":[{"type":"text","$t":"Hike Reviews"}]    
  
     //feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);      
      
      
      myService.insertEntry(eventsFeedURL, entrySample, insertEntryHandler2, insertEntryError);
    };
    
    
    function insertEntryHandler2(entryRoot) {
      var entry = entryRoot.entry;
      alert("inserido ok:" + entry.title.$t);
    };
    
    /**
     * Returns ISO 8601-compatible timezone offset as string
     */
    function getTimezoneOffset() {
      var hours, minutes;
      var offset, offsetString;
      offset = new Date().getTimezoneOffset();
      offset /= -60;

      hours = Math.floor(Math.abs(offset));
      minutes = Math.abs(offset)-hours;
      minutes *= 60;

      if (offset < 0)
        offsetString = '-';
      else {
        offsetString = '+';
      }

      if (hours < 10) {
        offsetString += '0';
      }
      offsetString += hours.toString()+':';

      if (minutes < 10) {
        offsetString += '0';
      }
      offsetString += minutes.toString();
      
      return offsetString;
    }
    
    /**
     * Called after successful insertion of new entry into selected calendar feed
     */
    function insertEntryHandler(entryRoot) {
      var eventsList = google.mashups.getObjectById('eventsList');
      var newEntry = eventsList.getData().createEntry();
      var entry = entryRoot.entry;
      
      var location = entry.getLocations()[0].getValueString();
      
      var startTime = google.gdata.DateTime.toIso8601(entry.getTimes()[0].getStartTime().getDate());
      var endTime = google.gdata.DateTime.toIso8601(entry.getTimes()[0].getEndTime().getDate());
      
      new GPath('atom:title').setValue(newEntry, entry.getTitle().getText());
      new GPath('gd:when/@startTime').setValue(newEntry, startTime);
      new GPath('gd:when/@endTime').setValue(newEntry, endTime);
      
      if (location) {
        new GPath('gd:where/@valueString').setValue(newEntry, location);
      }
		
      eventsList.getData().addEntry(newEntry);
    };
      
    /**
     * Creates a popup alert notifying user of error while attempting to insert new entry into
     * selected calendar feed
     * 
     * @param e  Error message string
     */
    function insertEntryError(e) {
       alert(e);
    };
    
    /**
     * Deletes all entries in specified GME list
     * 
     * @param listName  ID of list to be deleted
     */
    function deleteList(listName) {
      var list = google.mashups.getObjectById(listName);
      
      for (var i=list.getData().size()-1; i>=0; i--) {
        var entry = list.getData().entryAt(i);
        list.getData().removeEntry(entry);
      }
    }
  </script>
    
  <div class="gm-app-header">
    <h2>Integrating GME and the Google data APIs<h2>
  </div>
  
  <table style="width:80%" align="center">
    <tr>
      <td style="padding-top:20px; width:200px" valign="top">
        <div style="height:185px; width:250px">
          <gm:calendar id="calendar" data="${eventsList}">
            <gm:handleEvent src="eventsList"/>
            <gm:handleEvent src="map"/>
          </gm:calendar>
        </div>
        <div style="height:185px; width:218px">
          <!-- <gm:map id="map" style="border:solid silver 1px" height="185" width="218" data="${eventsList}" geolocationref="gd:where/@valueString">
            <gm:handleEvent src="eventsList"/>
            <gm:handleEvent src="calendar"/>
          </gm:map> -->
        </div>
      </td>
      <td style="padding-top:20px" valign="top">
        <input id="authenticationButton" type="button" value="Retrieve my calendars" onclick="authenticate()"/>
        <input id="authenticationButton2" type="button" value="Retrieve Again" onclick="newLoad()"/>
        <input id="authenticationButton3" type="button" value="Adiçona" onclick="addStuff()"/>
        
        <p/>
        <select id="calendarSelect" style="display:none" onchange="changeCalendar()">
          <option value="" selected="selected">- CHOOSE A CALENDAR -</option>
        </select>
        <p/>
        <div id="authenticatedContent" style="display:none; margin-top:20px">
          <gm:item data="${tmp}/newEvents" create="true" template="newEventItemTemplate"/>
          <p/>
          <gm:list id="eventsList" data="${tmp}/eventEntries" sort="dateSort" template="eventsListTemplate">
            <gm:sort name="dateSort" ref="gd:when/@startTime"/>
            <gm:handleEvent src="calendar"/>
            <gm:handleEvent src="map"/>
          </gm:list>
          
          <gm:list id="newEventsList" style="display:none" data="${tmp}/newEvents">
            <gm:handleEvent event="repaint" execute="addNewEvent()"/>
          </gm:list>
        </div>
      </td>
    </tr>
  </table>                  
                  

  <gm:template id="eventsListTemplate">
    <table id="eventsListTable" class="blue-theme">
      <thead>
        <tr>
          <th>Event name</th>
          <th>Start date</th>
          <th>End date</th>
        </tr>
      </thead>
      <tr repeat="true">
        <td><gm:text ref="atom:title"/></td>
        <td align="center"><gm:date ref="gd:when/@startTime"/></td>
        <td align="center"><gm:date ref="gd:when/@endTime"/></td>
      </tr>
      <tfoot>
        <tr>
          <td colspan="3"/>
        </tr>
      </tfoot>
    </table>
  </gm:template>
  <gm:template id="newEventItemTemplate">
    <div id="newEventItemContainer">
      <h3>Create a new event!</h3>
      <p/>
      <gm:text ref="atom:title" hint="Event name"/>
      <p/>
      <gm:text ref="gd:where/@valueString" hint="Event location"/>
      <p/>
      <table id="eventTimesTable">
      	<tr>
      	  <td>From</td>
      	  <td><gm:date ref="gd:when/@startTime"/></td>
      	  <td><gm:text ref="gmd:startTime" hint="e.g. 08:00"/></td>
      	  <td>to</td>
      	  <td><gm:date ref="gd:when/@endTime"/></td>
      	  <td><gm:text ref="gmd:endTime" hint="e.g. 19:00"/></td>
      	</tr>
      </table>
      <p/>
      <gm:editButtons text="true"/>
    </div>
  </gm:template>

</gm:page>
